package ace.module.account.core.impl.service.impl;

import ace.cmp.core.model.R;
import ace.cmp.core.utils.SystemClockUtils;
import ace.cmp.i18n.api.MessageSourceAssertService;
import ace.module.account.api.model.dto.IamAccountPasswordDto;
import ace.module.account.core.impl.converter.IamAccountPasswordConverter;
import ace.module.account.core.impl.dao.entity.IamAccountPassport;
import ace.module.account.core.impl.dao.entity.IamAccountPassword;
import ace.module.account.core.impl.dao.repository.IamAccountPasswordRepository;
import ace.module.account.core.impl.manager.IamAccountPassportManager;
import ace.module.account.core.impl.manager.IamAccountPasswordManager;
import ace.module.account.core.impl.service.IamAccountPasswordService;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author caspar
 * @date 2023/3/18 16:16
 */
@Component
@AllArgsConstructor
public class IamAccountPasswordServiceImpl implements IamAccountPasswordService {

  private final IamAccountPasswordRepository iamAccountPasswordRepository;
  private final IamAccountPasswordConverter iamAccountPasswordConverter;
  private final IamAccountPasswordManager iamAccountPasswordManager;
  private final IamAccountPassportManager iamAccountPassportManager;
  private final MessageSourceAssertService assertService;
  private final PasswordEncoder passwordEncoder;

  @Override
  public List<IamAccountPasswordDto> getByIamAppIdAndPassportAndPassportTypes(
      Long iamAppId, String passport, List<Integer> passportTypes) {
    List<IamAccountPassport> accountPassports =
        iamAccountPassportManager.getByIamAppIdAndTagAndPassportAndPassportTypes(
            iamAppId, passport, passportTypes);

    if (CollectionUtils.isEmpty(accountPassports)) {
      return ListUtils.EMPTY_LIST;
    }

    List<Long> accountIds = accountPassports.stream().map(p -> p.getIamAccountId()).collect(Collectors.toList());

    List<IamAccountPassword> accountPasswordList =
        iamAccountPasswordRepository.getByIamAccountIdIn(accountIds);

    return accountPasswordList.stream()
        .map(p -> this.iamAccountPasswordConverter.convert(p))
        .collect(Collectors.toList());
  }

  @Override
  public R<Void> modifyPassword(
      Long accountId, String oldPassword, String newPassword, String confirmPassword) {
    assertService.isTrue(
        StringUtils.equals(newPassword, oldPassword),
        "account.password.error-old-new-not-equal",
        "新密码与确认密码必须一致");
    IamAccountPassword iamAccountPassword = iamAccountPasswordManager.getAndCheckAllById(accountId);
    assertService.isFalse(
        passwordEncoder.matches(oldPassword, iamAccountPassword.getPassword()),
        "account.password.error-password",
        "密码错误");
    String encodePassword = passwordEncoder.encode(newPassword);
    iamAccountPassword.setPassword(encodePassword);
    iamAccountPassword.setUpdateTime(SystemClockUtils.currentTimeMillis());
    this.iamAccountPasswordRepository.updateById(iamAccountPassword);
    return R.ok();
  }
}
